home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d26 / xmas_etc.arc / DUDEL.C < prev    next >
Text File  |  1990-09-04  |  31KB  |  1,097 lines

  1. /* dudel.c by bill buckels 1990 */
  2. /* writing direct to screen     */
  3. /* using bios calls to set the adapter */
  4. /* compile using small memory model    */
  5.  
  6. #include <stdio.h>
  7. #include <string.h>
  8. #include <dos.h>
  9. #include <bios.h>
  10. #include <conio.h>
  11. #include <direct.h>
  12. #include <fcntl.h>
  13. #include <malloc.h>
  14.  
  15. #define CRETURN '\x0d'
  16. #define LFEED   '\x0A'
  17. #define CTRLZ   '\x1a'
  18. #define DELETE  '\x7f'
  19. #define ESCAPE  '\x1b'
  20.  
  21. #define ENTERKEY   '\x0d' /* character generated by the Enter key          */
  22. #define ESCKEY     '\x1b' /* character generated by the Esc key            */
  23. #define FUNCKEY    '\x00' /* first character generated by function keys    */
  24. #define HOMEKEY    'G'    /* second character generated by Home key        */
  25. #define ENDKEY     'O'    /* second character generated by End key         */
  26. #define UPARROW    'H'    /* second character generated by up-arrow key    */
  27. #define DOWNARROW  'P'    /* second character generated by down-arrow key  */
  28. #define LEFTARROW  'K'    /* second character generated by left-arrow key  */
  29. #define RIGHTARROW 'M'    /* second character generated by right-arrow key */
  30. #define INSERTKEY  'R'    /* second character generated by insert key      */
  31. #define PGUP       'I'    /* second character generated by page up key     */
  32. #define PGDOWN     'Q'    /* second character generated by page down key   */
  33.  
  34. #define BLANK     32
  35. #define FAT       219
  36. #define SINGLE    1
  37. #define DOUBLE    2
  38.  
  39. /* starting at character 59*/
  40. #define F1         ';'    /* second character generated by numerical fkeys */
  41. #define F2         '<'
  42. #define F3         '='
  43. #define F4         '>'
  44. #define F5         '?'
  45. #define F6         '@'
  46. #define F7         'A'
  47. #define F8         'B'
  48. #define F9         'C'
  49. #define F10        'D'
  50. /* ending at character 68  */
  51.  
  52.  
  53. #define BLACK   0
  54. #define BLUE    1
  55. #define GREEN   2
  56. #define CYAN    3
  57. #define RED     4
  58. #define MAGENTA 5
  59. #define BROWN   6
  60. #define WHITE   7
  61. #define GRAY      8
  62. #define LBLUE     9
  63. #define LGREEN    10
  64. #define LCYAN     11
  65. #define LRED      12
  66. #define LMAGENTA  13
  67. #define YELLOW    14
  68. #define BWHITE    15
  69.  
  70. #define CGA  3
  71. #define HERCULES 99
  72.  
  73. int ADAPTER = CGA   ;
  74.  
  75. unsigned char far *crt;
  76. unsigned char far *romfont;
  77. unsigned char *screenbuffer;
  78. unsigned char *helpbuffer;
  79.  
  80. #define SCREENSIZE 4000
  81.  
  82.  
  83. int dude=0;
  84.  
  85. /* a microsoft compatible bsaved memory image format descriptor */
  86. unsigned char BSV_header[7]={
  87.  
  88.     '\xfd',          /* ID Flag = file descriptor identifier bsaved file */
  89.  
  90.    /* afew words about what BASIC does with this header */
  91.    /* and afew words about extending BASIC's ability to */
  92.    /* read and use BINARY files created in this manner. */
  93.  
  94.     /* BASIC will use original segment and offset information  */
  95.     /* to reload a memory image unless "DEF SEG" has been used */
  96.     /* and then an explicit offset is used as the second arg   */
  97.     /* of the bload command. */
  98.  
  99.     /* subsequently, once DEF SEG is invoked  */
  100.     /* If an offset is specified without then */
  101.     /* first calling DEF SEG, The image will then be loaded to */
  102.     /* the segment specified in the last segment pointed to    */
  103.     /* by the last call to DEF SEG. DEF SEG without args returns */
  104.     /* to DGROUP (the default data segment) and resets the thing.*/
  105.  
  106.     /* we can also implement and store an array in memory by use of */
  107.     /* VARSEG and VARPTR to obtain the window for the array's       */
  108.     /* memory location, i.e. override the defaults by windowing     */
  109.     /* to the array base using DEF SEG = VARSEG(arrayname) then to     */
  110.     /* fill the array we would use BLOAD bsaved.bsv, VARPTR(arrayname) */
  111.     /* using VARPTR to point to the offset from the memory base segment*/
  112.  
  113.     '\x00', '\xb8',  /* base address     = MSB | LSB original segment    */
  114.     '\x00', '\x00',  /* offset from base = MSB | LSB original offset     */
  115.  
  116.     '\xA0', '\x0F'   /* file size = MSB | LSB of bytes to be loaded +    */
  117.                      /* size of descriptors in bytes (8)                 */
  118.     };
  119.  
  120. unsigned char BSAVED_tailer[1]={
  121.     '\x1A'
  122.     };
  123.  
  124. int dudesave()
  125. {
  126.     /* a quicksave routine */
  127.     FILE *fp;
  128.     int i;
  129.     int buffer[66];
  130.     static char far *temp;
  131.  
  132.     if(ADAPTER==HERCULES)BSV_header[2]= '\xb0';
  133.  
  134.     sprintf(buffer,"DUDE%d.BSV",dude);
  135.     while((fp=fopen(buffer,"rb"))!=NULL)
  136.     {
  137.         fclose(fp);
  138.         dude++;
  139.         sprintf(buffer,"DUDE%d.BSV",dude);
  140.         }
  141.    if((fp=fopen(buffer,"wb"))==NULL)return -1;
  142.  
  143.    for(i=0;i!=7;i++)fputc(BSV_header[i],fp);
  144.    temp=crt;
  145.    i=SCREENSIZE;
  146.    while(i-->0)fputc(*temp++,fp);
  147.    fputc(BSAVED_tailer[0],fp);
  148.    fclose(fp);
  149.    return 0;
  150. }
  151.  
  152. void savescreen(unsigned char *buf)
  153. {
  154.     static unsigned char far *temp;
  155.     int i=SCREENSIZE;
  156.  
  157.     temp=crt;
  158.     while(i-->0)*buf++=*temp++;
  159. }
  160.  
  161. void restorescreen(unsigned char *buf)
  162. {
  163.     static unsigned char far *temp;
  164.     int i=SCREENSIZE;
  165.  
  166.     temp=crt;
  167.     while(i-->0)*temp++=*buf++;
  168. }
  169.  
  170. void cursoroff(void)
  171. {
  172.    union REGS regs;
  173.  
  174.    regs.h.ah = 0x01;
  175.    regs.x.cx = 0x2000;
  176.    int86(0x10,®s,®s);
  177. }
  178.  
  179.  
  180. void cursoron(void)
  181. {
  182.    union REGS regs;
  183.  
  184.    regs.h.ah = 0x01;
  185.    regs.x.cx = 0x0607;
  186.    int86(0x10,®s,®s);
  187. }
  188.  
  189.  
  190. void cls(int BACK,int FRONT)
  191. {
  192.     union REGS reg;
  193.  
  194.     reg.h.ah = 6;
  195.     reg.h.al = 0;
  196.     reg.h.ch = 0;
  197.     reg.h.cl = 0;
  198.     reg.h.dh = 24;
  199.     reg.h.dl = 79;
  200.     reg.h.bh = (BACK << 4) + FRONT;
  201.     int86(0x10, ®, ®);
  202. }
  203.  
  204.  
  205. int colorset(background, palette)
  206. unsigned char background, palette;
  207. {
  208.     union REGS rin,rout;
  209.     
  210.     if(ADAPTER==HERCULES) return 0;
  211.     rin.h.ah = 11;
  212.     rin.h.bh = 0;
  213.     rin.h.bl = background;
  214.     int86(0x10,&rin,&rout);
  215.     rin.h.bh = 1;
  216.     rin.h.bl = palette;
  217.     int86(0x10,&rin,&rout);
  218.     return 0;
  219. }
  220.  
  221.  
  222. void DMC(int Row, int Column, unsigned BYTE, int BACK, int FRONT, int QUANT)
  223. {
  224.     /*  DMA replacement for writechs function */
  225.  
  226.     unsigned segment= 0xB000, offset;
  227.     int One_Too_Many = (QUANT+1);
  228.     int i, Attribute;
  229.  
  230.     Attribute = (BACK << 4) + FRONT;
  231.  
  232.     if(ADAPTER!=HERCULES)segment = 0xB800;    /* CGA or Equivalent */
  233.     offset = 160 * Row + 2 * Column ;
  234.     for (i=1; i< One_Too_Many ; i++){
  235.         poke(segment,offset, BYTE|Attribute<<8);
  236.         offset+=2;
  237.         }
  238. }
  239.  
  240.  
  241. void DMM(char *String, int Row, int Column, int BACK, int FRONT)
  242. {
  243.     /*  DMA replacement for puts
  244.         centre justified string    */
  245.  
  246.     unsigned Character, segment=0xB000, offset;
  247.     int Attribute;
  248.  
  249.     Attribute = (BACK << 4) + FRONT;
  250.  
  251.     Column =   ((Column+1)-(.5*(strlen(String))));
  252.  
  253.     if(ADAPTER != HERCULES)segment = 0xB800;    /* CGA or Equivalent */
  254.     offset = 160 * Row + 2 * Column ;
  255.     while ((Character = *String++)!=0){
  256.         if(Character!='\n'){
  257.         poke(segment,offset,Character|Attribute<<8);
  258.         offset+=2;
  259.         }
  260.         }
  261. }
  262.  
  263.  
  264. void DML(char *String, int Row, int Column, int BACK, int FRONT)
  265. {
  266.     /*  DMA replacement for puts
  267.         left justified string    */
  268.     unsigned Character, segment=0xB000, offset;
  269.     int Attribute;
  270.  
  271.     Attribute = (BACK << 4) + FRONT;
  272.  
  273.     if(ADAPTER!=HERCULES)segment = 0xB800; /* CGA or Equivalent */
  274.     offset = 160 * Row + 2 * Column ;
  275.     while ((Character = *String++)!=0){
  276.         if(Character!='\n'){
  277.         poke(segment,offset, Character|Attribute<<8);
  278.         offset +=2;
  279.         }
  280.     }
  281. }
  282.  
  283.  
  284.  
  285. void getadaptertype(void)
  286. {
  287.     if(((biosequip() >>4) &3) <3)ADAPTER=CGA;
  288.     else ADAPTER=HERCULES;
  289. }
  290.  
  291. /* musical arrays */
  292.  
  293. int danube[]=
  294. {
  295. 294,4,371,4,441,4,441,4,32767,4,882,2,32767,2,882,2,
  296. 32767,6,742,2,32767,2,742,2,32767,6,294,4,294,4,371,4,
  297. 441,4,441,4,32767,4,882,2,32767,2,882,2,32767,6,786,2,
  298. 32767,2,786,2,32767,6,278,4,278,4,330,4,495,4,495,4,
  299. 32767,4,990,2,32767,2,990,2,32767,6,786,2,32767,2,786,2,
  300. 32767,6,278,4,278,4,330,4,495,4,495,4,32767,4,990,2,
  301. 32767,2,990,2,32767,6,742,2,32767,2,742,2,32767,6,294,4,
  302. 294,4,371,4,441,4,589,4,32767,4,1178,2,32767,2,1178,2,
  303. 32767,6,882,2,32767,2,882,2,32767,6,294,4,294,4,371,4,
  304. 441,4,589,4,32767,4,1178,2,32767,2,1178,2,32767,6,990,2,
  305. 32767,2,990,2,32767,6,330,4,330,4,393,4,495,2,32767,2,
  306. 495,14,32767,2,416,4,441,4,742,16,589,4,371,4,371,8,
  307. 330,4,495,8,441,4,294,4,32767,2,294,2,294,4,32767,8,
  308. 441,2,32767,2,393,2,32767,6,441,2,32767,2,393,2,32767,6,
  309. 441,4,742,16,661,4,441,2,32767,2,371,2,32767,6,441,2,
  310. 32767,2,371,2,32767,6,441,4,661,16,589,4,441,2,32767,2,
  311. 393,2,32767,6,441,2,32767,2,393,2,32767,6,441,4,742,16,
  312. 661,4,441,4,589,4,661,4,742,4,882,8,786,4,742,2,
  313. 742,2,742,4,661,2,32767,2,589,4,32767,8,-1,-1
  314. /* the blue danube walz -strauss */
  315. };
  316.  
  317. int dvorak[]=
  318. {
  319. 393,3,32767,2,441,1,393,3,32767,2,441,1,495,3,32767,2,
  320. 589,1,661,3,32767,2,589,1,786,3,32767,2,742,1,882,3,
  321. 32767,2,786,1,742,3,32767,2,882,1,786,3,32767,2,661,1,
  322. 589,3,32767,2,589,1,661,3,32767,2,589,1,786,3,32767,2,
  323. 661,1,589,3,32767,2,495,1,441,24,393,3,32767,2,441,1,
  324. 393,3,32767,2,441,1,495,3,32767,2,589,1,661,3,32767,2,
  325. 589,1,661,3,32767,2,742,1,882,3,32767,2,786,1,742,3,
  326. 32767,2,882,1,786,3,32767,2,661,1,589,3,32767,2,589,1,
  327. 786,3,32767,2,393,1,441,6,589,6,393,18,-1,-1
  328. /* humoresque by dvorak */
  329. };
  330.  
  331. int guonod[]=
  332. {
  333. 221,1,32767,2,147,1,32767,5,294,3,294,3,278,3,248,3,
  334. 278,3,32767,3,294,3,330,3,32767,3,221,1,32767,2,147,1,
  335. 32767,5,294,3,294,3,278,3,248,3,278,3,32767,3,294,3,
  336. 330,3,32767,3,221,3,294,3,32767,3,350,3,441,6,393,3,
  337. 350,3,32767,3,441,3,525,6,467,3,441,3,32767,3,556,3,
  338. 661,6,589,3,556,3,467,3,441,3,393,3,350,3,330,3,
  339. 147,1,32767,5,294,3,294,3,278,3,248,3,278,3,32767,3,
  340. 294,3,330,3,32767,3,221,1,32767,2,147,1,32767,5,294,3,
  341. 294,3,278,3,248,3,278,3,32767,3,294,3,330,3,32767,3,
  342. 221,3,350,3,32767,3,441,3,525,6,467,3,441,3,393,3,
  343. 350,3,312,3,393,3,467,3,294,3,278,3,294,3,330,3,
  344. 32767,3,350,1,32767,2,330,9,294,1,-1,-1
  345. /* funeral march of a marionette by guonod */
  346. };
  347.  
  348. int mexico[]=
  349. {
  350. 525,2,700,2,32767,2,525,2,700,2,32767,2,525,2,700,6,
  351. 32767,4,525,2,700,2,786,2,700,2,661,4,700,2,786,2,
  352. 32767,8,525,2,661,2,32767,2,525,2,661,2,32767,2,525,2,
  353. 661,6,32767,4,525,2,661,2,700,2,661,2,589,4,661,2,
  354. 700,2,32767,6,1049,2,990,2,1049,2,882,2,833,2,882,2,
  355. 700,2,661,2,700,2,525,2,32767,4,441,2,467,2,525,2,
  356. 589,2,661,2,700,2,786,2,882,2,935,2,786,2,32767,4,
  357. 935,2,882,2,935,2,786,2,742,2,786,2,661,2,624,2,
  358. 661,2,525,2,32767,4,1049,2,990,2,1049,2,1178,2,1049,2,
  359. 935,2,882,2,786,2,700,2,-1,-1
  360. /* mexican hat dance */
  361. };
  362.  
  363. int mozart[]=
  364. {
  365. 624,2,589,2,589,4,624,2,589,2,589,4,624,2,589,2,
  366. 589,4,935,4,32767,4,935,2,882,2,786,4,786,2,700,2,
  367. 624,4,624,2,589,2,525,4,525,4,32767,4,589,2,525,2,
  368. 525,4,589,2,525,2,525,4,589,2,525,2,525,4,882,4,
  369. 32767,4,882,2,786,2,742,4,742,2,624,2,589,4,589,2,
  370. 525,2,467,4,467,4,32767,4,935,2,882,2,882,4,1049,4,
  371. 742,4,882,4,786,4,589,4,32767,4,935,2,882,2,882,4,
  372. 1049,4,742,4,882,4,786,4,935,4,882,2,786,2,700,2,
  373. 624,2,589,4,371,4,393,4,441,4,467,4,525,2,467,2,
  374. 441,4,393,4,589,4,32767,4,1112,8,1178,2,32767,6,1112,8,
  375. 1178,2,32767,6,1112,8,1178,4,1112,4,1178,4,1112,4,1178,4,-1,-1
  376. /* symphony #40 by wolfgang mozart */
  377. };
  378.  
  379. int sam[]=
  380. {
  381. 523,3,32767,1,523,3,32767,1,587,3,32767,1,659,3,32767,1,
  382. 523,3,32767,1,659,3,32767,1,587,3,32767,1,392,3,32767,1,
  383. 523,3,32767,1,523,3,32767,1,587,3,32767,1,659,3,32767,1,
  384. 523,6,32767,1,392,6,32767,2,523,3,32767,1,523,3,32767,1,
  385. 587,3,32767,1,659,3,32767,1,698,3,32767,1,659,3,32767,1,
  386. 587,3,32767,1,523,3,32767,1,493,3,32767,1,493,3,32767,1,
  387. 440,3,32767,1,493,3,32767,1,523,6,32767,1,523,6,32767,3,-1,-1
  388. /* yankee doodle */
  389. };
  390.  
  391. int stars[]=
  392. {
  393. 589,6,589,6,525,3,495,3,495,6,467,3,495,3,495,16,32767,2,
  394. 467,3,495,3,495,6,467,3,495,3,589,6,495,3,589,3,525,12,
  395. 441,6,32767,3,441,3,441,6,416,3,441,3,441,6,416,3,441,3,
  396. 525,16,32767,2,495,3,441,3,495,3,589,9,661,9,661,3,441,16,
  397. 32767,2,589,6,589,6,525,3,495,3,495,6,467,3,495,3,495,16,
  398. 32767,2,467,3,495,3,495,6,467,3,495,3,525,3,495,3,441,5,
  399. 371,1,441,12,393,6,32767,3,393,3,393,6,371,3,393,3,467,6,
  400. 441,3,393,3,786,15,32767,3,393,3,441,3,495,3,589,1,32767,2,
  401. 393,3,441,3,495,3,589,1,32767,2,294,3,330,5,495,1,441,12,393,1,
  402. -1,-1
  403. /* the stars and stripes forever
  404.    john p. sousa  */
  405. };
  406.  
  407. int bug[]=
  408. {
  409. 294,1,32767,1,294,1,32767,1,294,1,32767,1,393,1,32767,5,
  410. 495,1,32767,3,294,1,32767,1,294,1,32767,1,294,1,32767,1,
  411. 393,1,32767,5,495,1,32767,5,147,1,32767,1,147,1,32767,1,
  412. 196,1,32767,3,393,1,32767,1,393,1,32767,1,371,1,32767,1,
  413. 371,1,32767,1,330,1,32767,1,330,1,32767,1,294,8,32767,2,
  414. 294,1,32767,1,294,1,32767,1,294,1,32767,1,371,1,32767,5,
  415. 441,1,32767,3,294,1,32767,1,294,1,32767,1,294,1,32767,1,
  416. 371,1,32767,5,441,1,32767,5,221,1,32767,1,221,1,32767,1,
  417. 147,1,32767,3,589,2,661,2,589,2,525,2,495,2,441,2,393,8,-1,-1
  418. /* archie and mehitabel's lovesong */
  419. };
  420.  
  421. int weasel[]=
  422. {
  423. 393,2,32767,2,393,2,441,2,32767,2,441,2,495,2,589,2,
  424. 495,2,393,2,32767,2,294,2,393,2,32767,2,393,2,441,2,
  425. 32767,2,441,2,495,6,393,2,32767,2,294,2,393,2,32767,2,
  426. 393,2,441,2,32767,2,441,2,495,2,589,2,495,2,393,2,
  427. 32767,4,661,2,32767,4,441,2,32767,2,525,2,495,6,393,2,
  428. 32767,4,786,2,32767,2,786,2,661,2,32767,2,786,2,742,2,
  429. 882,2,742,2,589,2,32767,4,786,2,32767,2,786,2,661,2,
  430. 32767,2,786,2,742,6,589,2,32767,2,495,2,525,2,32767,2,
  431. 495,2,525,2,32767,2,589,2,661,2,32767,2,742,2,786,2,
  432. 32767,4,661,2,32767,4,441,2,32767,2,525,2,495,6,393,2,-1,-1
  433. /* popgoestheweasel */
  434. };
  435.  
  436.  
  437. int background2=WHITE,foreground2=BLACK;
  438. int ratherlargefont(char *str)
  439. {
  440.      int target = strlen(str);
  441.      int scanline,row,linebase,byte,nibble;
  442.      int col,col2,att,att2;
  443.      int attr = (background2<< 4) + foreground2;
  444.  
  445.      char character;
  446.  
  447.      linebase = 5 * 160 + 82 - (target * 16);
  448.  
  449.  for(scanline=0;scanline!=8;scanline++)
  450.     {
  451.     row = linebase + (scanline * 2 * 160);
  452.  
  453.     for (byte=0;byte<target;byte++)
  454.      {
  455.       character= romfont[(str[byte]&0x7f)*8+scanline];
  456.       col = row + (byte* 32);
  457.       att = col + 1         ;
  458.       col2 = col + 160      ;
  459.       att2 = att + 160      ;
  460.  
  461.       for (nibble=0;nibble<8;nibble++)
  462.                     {
  463.                     if (character & 0x80>>nibble){
  464.                         crt[col] =str[byte];crt[att]=attr ;
  465.                         crt[col2]=str[byte];crt[att2]=attr;
  466.                         }
  467.                         col+= 2;att+= 2;col2+=2;att2+=2;
  468.                     if (character & 0x80>>nibble){
  469.                         crt[col] =str[byte];crt[att]=attr ;
  470.                         crt[col2]=str[byte];crt[att2]=attr;
  471.                         }
  472.                         col+= 2;att+= 2;col2+=2;att2+=2;
  473.                         }
  474.                     }
  475.                 }
  476. }
  477.  
  478.  
  479. int mus_ctr=0;
  480. int SND=1;
  481.  
  482. int playmusic()
  483. {
  484.    int frequency,duration;
  485.  
  486.    TOP:;
  487.  
  488.     switch(SND)
  489.     {
  490.                /* a donothing loop to seat the cursor*/
  491.       case 0 : for(duration=0;duration<SCREENSIZE;duration++);return 0;
  492.       case -1: SND=1;
  493.       case  1: frequency=danube[mus_ctr];
  494.               if(frequency!=-1)
  495.                 {
  496.                  mus_ctr++;
  497.                  duration=danube[mus_ctr];
  498.                  mus_ctr++;
  499.                  break;
  500.                  }
  501.              mus_ctr=0;
  502.              SND++;
  503.        case 2: frequency=dvorak[mus_ctr];
  504.               if(frequency!=-1)
  505.                 {
  506.                  mus_ctr++;
  507.                  duration=dvorak[mus_ctr];
  508.                  mus_ctr++;
  509.                  break;
  510.                  }
  511.              mus_ctr=0;
  512.              SND++;
  513.        case 3: frequency=guonod[mus_ctr];
  514.               if(frequency!=-1)
  515.                 {
  516.                  mus_ctr++;
  517.                  duration=guonod[mus_ctr];
  518.                  mus_ctr++;
  519.                  break;
  520.                  }
  521.              mus_ctr=0;
  522.              SND++;
  523.        case 4: frequency=mexico[mus_ctr];
  524.               if(frequency!=-1)
  525.                 {
  526.                  mus_ctr++;
  527.                  duration=mexico[mus_ctr];
  528.                  mus_ctr++;
  529.                  break;
  530.                  }
  531.              mus_ctr=0;
  532.              SND++;
  533.        case 5: frequency=mozart[mus_ctr];
  534.               if(frequency!=-1)
  535.                 {
  536.                  mus_ctr++;
  537.                  duration=mozart[mus_ctr];
  538.                  mus_ctr++;
  539.                  break;
  540.                  }
  541.              mus_ctr=0;
  542.              SND++;
  543.         case 6: frequency=sam[mus_ctr];
  544.               if(frequency!=-1)
  545.                 {
  546.                  mus_ctr++;
  547.                  duration=sam[mus_ctr];
  548.                  mus_ctr++;
  549.                  break;
  550.                  }
  551.              mus_ctr=0;
  552.              SND++;
  553.         case 7: frequency=stars[mus_ctr];
  554.               if(frequency!=-1)
  555.                 {
  556.                  mus_ctr++;
  557.                  duration=stars[mus_ctr];
  558.                  mus_ctr++;
  559.                  break;
  560.                  }
  561.              mus_ctr=0;
  562.              SND++;
  563.         case 8: frequency=bug[mus_ctr];
  564.               if(frequency!=-1)
  565.                 {
  566.                  mus_ctr++;
  567.                  duration=bug[mus_ctr];
  568.                  mus_ctr++;
  569.                  break;
  570.                  }
  571.              mus_ctr=0;
  572.              SND++;
  573.          case 9: frequency=weasel[mus_ctr];
  574.               if(frequency!=-1)
  575.                 {
  576.                  mus_ctr++;
  577.                  duration=weasel[mus_ctr];
  578.                  mus_ctr++;
  579.                  break;
  580.                  }
  581.         default: mus_ctr=0;
  582.                  SND=-1;
  583.                  }
  584.  
  585.         if(SND<0)goto TOP;
  586.         sound(frequency,duration);
  587.         return 0;
  588. }
  589.  
  590.  
  591. /* displays a series of files of a certain type */
  592.  
  593. char wildfiles[200][15];
  594.  
  595. int filecords[84][2]=
  596. {
  597.     2,  4,  2,  23,  2, 42,  2, 61,
  598.     3,  4,  3,  23,  3, 42,  3, 61,
  599.     4,  4,  4,  23,  4, 42,  4, 61,
  600.     5,  4,  5,  23,  5, 42,  5, 61,
  601.     6,  4,  6,  23,  6, 42,  6, 61,
  602.     7,  4,  7,  23,  7, 42,  7, 61,
  603.     8,  4,  8,  23,  8, 42,  8, 61,
  604.     9,  4,  9,  23,  9, 42,  9, 61,
  605.     10, 4, 10,  23, 10, 42, 10, 61,
  606.     11, 4, 11,  23, 11, 42, 11, 61,
  607.     12, 4, 12,  23, 12, 42, 12, 61,
  608.     13, 4, 13,  23, 13, 42, 13, 61,
  609.     14, 4, 14,  23, 14, 42, 14, 61,
  610.     15, 4, 15,  23, 15, 42, 15, 61,
  611.     16, 4, 16,  23, 16, 42, 16, 61,
  612.     17, 4, 17,  23, 17, 42, 17, 61,
  613.     18, 4, 18,  23, 18, 42, 18, 61,
  614.     19, 4, 19,  23, 19, 42, 19, 61,
  615.     20, 4, 20,  23, 20, 42, 20, 61,
  616.     21, 4, 21,  23, 21, 42, 21, 61,
  617.     22, 4, 22,  23, 22, 42, 22, 61};
  618.  
  619. int getfiles(char *filetype)
  620. {
  621.  
  622.     char buffer[15];
  623.     int wildcounter=0;
  624.  
  625.     struct ffblk wild_card;
  626.  
  627.     memset(wildfiles,0,sizeof(wildfiles));
  628.     sprintf(buffer,"*.%s",filetype);
  629.  
  630.     if(findfirst(buffer,&wild_card,FA_NORMAL)==0)
  631.     {
  632.         strcpy(wildfiles[wildcounter],wild_card.ff_name);
  633.         wildcounter++;
  634.  
  635.     while(findnext(&wild_card)==0){
  636.            strcpy(wildfiles[wildcounter],wild_card.ff_name);
  637.            wildcounter++;
  638.            }
  639.            }
  640.            /* alpha sort */
  641.            qsort(wildfiles,wildcounter,15,strcmp);
  642. return wildcounter;
  643. }
  644.  
  645. void PAINT(int *cor,int fore, int bk,unsigned char Character)
  646. {
  647.    int trow=cor[0],tcol=cor[1],brow=cor[2],bcol=cor[3];
  648.    int index,linelength = ((bcol+1) - (tcol));
  649.    for (index = (trow); index < brow+1; index++)
  650.    DMC(index,tcol,Character,bk,fore,linelength);
  651. }
  652.  
  653. void BORDERBOX(int *cor,int fore, int bk,unsigned char BRDR)
  654. {
  655.  
  656. int trow=cor[0],tcol=cor[1],brow=cor[2],bcol=cor[3];
  657.     /* draws an outline only using a specified border character */
  658. int index;
  659. int homerow = (brow-1);
  660. int homecol = (tcol+1);
  661. int linelength = ((bcol) - (tcol+1));
  662.  
  663. int TLcorner,TRcorner,BLcorner,BRcorner,HORT,VERT;
  664.  
  665.           switch(BRDR){
  666.                case DOUBLE: {
  667.                             TLcorner = 201;
  668.                             TRcorner = 187;
  669.                             BLcorner = 200;
  670.                             BRcorner = 188;
  671.                             HORT = 205;
  672.                             VERT = 186;
  673.                             break;
  674.                         }
  675.                case SINGLE: {
  676.                             TLcorner = 218;
  677.                             TRcorner = 191;
  678.                             BLcorner = 192;
  679.                             BRcorner = 217;
  680.                             HORT = 196;
  681.                             VERT = 179;
  682.                             break;
  683.                         }
  684.                default:    {
  685.                             TLcorner = BRDR;
  686.                             TRcorner = BRDR;
  687.                             BLcorner = BRDR;
  688.                             BRcorner = BRDR;
  689.                             HORT = BRDR;
  690.                             VERT = BRDR;
  691.                         }
  692.             }
  693.    DMC(trow,tcol,TLcorner,bk,fore,1);         /* top */
  694.    DMC(trow,homecol,HORT,bk,fore,linelength);
  695.    DMC(trow,bcol,TRcorner,bk,fore,1);
  696.    for (index = (trow+1); index < brow; index++){
  697.        DMC(index,tcol,VERT,bk,fore,1);
  698.        DMC(index,bcol,VERT,bk,fore,1);
  699.        }
  700.    DMC(brow,tcol,BLcorner,bk,fore,1);
  701.    DMC(brow,homecol,HORT,bk,fore,linelength);
  702.    DMC(brow,bcol,BRcorner,bk,fore,1);        /* bottom */
  703. }
  704.  
  705.  
  706.  
  707. int bload(char *name)
  708. {
  709.     unsigned char databuf[7];
  710.     static unsigned char *buf;
  711.     static unsigned char far *temp;
  712.  
  713.     int i,fh;
  714.  
  715.     temp=crt;
  716.     buf=screenbuffer;
  717.  
  718.     fh = open(name,O_RDONLY|O_BINARY);
  719.     read(fh,databuf,7);
  720.  
  721.     if(databuf[0]== '\xfd' && databuf[1]== 0)
  722.     {
  723.      read(fh,screenbuffer,SCREENSIZE);
  724.      close(fh);
  725.      i=SCREENSIZE;
  726.      while(i-->0)*temp++=*buf++;
  727.      return 0;
  728.      }
  729.      close(fh);
  730.      return -1;
  731. }
  732.  
  733. char *onlinehelp[22]={
  734. "",
  735. "Dudel is an Alphabetical Musical Doodlebug for Grades N-2.",
  736. "",
  737. "The Standard KeyBoard Keys Can Be Used To Select The Current DrawLetter.",
  738. "and Function Keys F1 through F10 are Option Switches.",
  739. "",
  740. "The Cursor Keys Control The Placement Of The Cursor.",
  741. "",
  742. "*** Function Keys and Their Use in Dudel ***",
  743. "",
  744. "F1 - On-line Help *** F2 - Sound Toggle *** F3,F4 - Background Color",
  745. "F5,F6 - Foreground Color  ***  F7 - Extended Character Set",
  746. "F8 - Clears the Screen To Current Settings",
  747. "F9 - Save Current Picture ***  F10 - Load A Picture From Disk",
  748. "",
  749. "*** Cursor Keys and Their Use in Dudel ***",
  750. "",
  751. "UPARROW- Up One ** DOWNARROW- Down One ** PAGEUP- Top Of Screen",
  752. "LEFTARROW- Left One ** RIGHTARROW- Right One ** PAGEDOWN- Bottom Of Screen",
  753. "HOME- Top Left Corner ** END- Bottom Right Corner",
  754. "",
  755. "*** Screens are Saved In The BSAVED IMAGE FORMAT ***"};
  756.  
  757.  
  758.  
  759.  
  760. int makehelp()
  761. {
  762.    int i;
  763.    char c;
  764.    int background = BLUE, foreground = YELLOW;
  765.    int cor[4];
  766.    int breverse=RED,freverse=YELLOW;
  767.  
  768.    if(ADAPTER==HERCULES){
  769.                          breverse=WHITE;
  770.                          freverse=BLACK;
  771.                          }
  772.    savescreen(helpbuffer);
  773.    cls(background, foreground);
  774.  
  775.    cor[0]=0;
  776.    cor[1]=0;
  777.    cor[2]=24;
  778.    cor[3]=79;
  779.  
  780.    BORDERBOX(cor,freverse,breverse,DOUBLE);
  781.    DMC(0,1,1,breverse,freverse,78);
  782.    DMM(" Dudel(C) Copyright 1990 by Teacher's Choice(tm) Productions ",
  783.    0,40,breverse,freverse);
  784.    DMM(
  785.    " On-Line Help. Press ESCape to Return to the Previous Screen ",
  786.         24,40,RED,YELLOW);
  787.  
  788.    for(i=0;i<22;i++)DMM(onlinehelp[i],(i+1),40,
  789.        background,foreground);
  790.    while((c=getch())!=ESCKEY);
  791.    restorescreen(helpbuffer);
  792.    return 0;
  793.  
  794. }
  795.  
  796. int displayfiles(char *filetype)
  797. {
  798.    int i;
  799.    int hotfile= 0;
  800.    int coldfile=0;
  801.    int filecount = getfiles(filetype);
  802.    char c;
  803.    int background = BLUE, foreground = YELLOW;
  804.    int cor[4];
  805.    int breverse=RED,freverse=YELLOW;
  806.  
  807.    if(filecount==0)return 0;
  808.    if(ADAPTER==HERCULES){
  809.                          breverse=WHITE;
  810.                          freverse=BLACK;
  811.                          }
  812.    savescreen(screenbuffer);
  813.    cls(background, foreground);
  814.  
  815.    cor[0]=0;
  816.    cor[1]=0;
  817.    cor[2]=24;
  818.    cor[3]=79;
  819.  
  820.    BORDERBOX(cor,freverse,breverse,DOUBLE);
  821.    DMC(0,1,1,breverse,freverse,78);
  822.    DMM(" Dudel(C) Copyright 1990 by Teacher's Choice(tm) Productions ",
  823.    0,40,breverse,freverse);
  824.    DMM(
  825.    " Use Arrow Keys to Select and Press Enter to Load: ESCape to Exit ",
  826.         24,40,RED,YELLOW);
  827.  
  828.  
  829.    if(filecount>84)filecount=84;
  830.  
  831.  
  832.    for(i=0;i<filecount;i++)
  833.        DML(wildfiles[i],filecords[i][0],filecords[i][1],
  834.        background,foreground);
  835.        DML(wildfiles[hotfile],filecords[hotfile][0],filecords[hotfile][1],
  836.        breverse,freverse);
  837.  
  838.    while((c=getch())!=ESCKEY)
  839.     {
  840.         if(c==ENTERKEY){
  841.                         bload(wildfiles[hotfile]);
  842.                         return 0;
  843.                         }
  844.         if(c==FUNCKEY)
  845.         {
  846.             c=getch();
  847.             switch(c)
  848.             {
  849.               case UPARROW  : if(hotfile<4)break;
  850.                               hotfile-=4;
  851.                               break;
  852.  
  853.               case DOWNARROW: if(hotfile>(filecount-5))break;
  854.                               hotfile+=4;
  855.                               break;
  856.  
  857.               case RIGHTARROW:
  858.                               if(hotfile<(filecount-1))
  859.                               hotfile++;
  860.                               break;
  861.  
  862.               case LEFTARROW: if(hotfile==0)break;
  863.                               hotfile--;
  864.                               break;
  865.               case F1       : makehelp();break;
  866.               }
  867.             }
  868.               if(hotfile!=coldfile)
  869.               {
  870.                 DML(wildfiles[coldfile],
  871.                     filecords[coldfile][0],filecords[coldfile][1],
  872.                     background,foreground);
  873.                 DML(wildfiles[hotfile],
  874.                     filecords[hotfile][0],filecords[hotfile][1],
  875.                     breverse,freverse);
  876.                     coldfile=hotfile;
  877.                     }
  878.                 }
  879.  
  880.    restorescreen(screenbuffer);
  881.    return 0;
  882.  
  883. }
  884.  
  885. void initialization()
  886. {
  887.     
  888.     unsigned int fontseg=0xffa6, fontoff=0x000e;
  889.  
  890.     if(ADAPTER==HERCULES)crt=MK_FP(0xb000,0x000);
  891.     else crt = MK_FP(0xb800,0x000);
  892.     romfont = MK_FP(fontseg,fontoff);
  893.     screenbuffer=malloc(4000);
  894.     helpbuffer= malloc(4000);
  895. }
  896.  
  897. void deinitialize()
  898. {
  899.     free(screenbuffer);
  900.     free(helpbuffer);
  901. }
  902.  
  903.  
  904. int playmexico(void)
  905. {
  906.     int duration,i=0;
  907.     int frequency=mexico[i];
  908.     char c;
  909.  
  910.     while(frequency!=-1)
  911.     {
  912.         i++;
  913.         duration=mexico[i];
  914.         if(kbhit()){
  915.              c=getch();
  916.              if(c==27)return 0;
  917.              if(c==0){
  918.                 c=getch();
  919.                 if(c==F1)makehelp();
  920.                 }
  921.                 }
  922.         sound(frequency, duration);
  923.         i++;
  924.         frequency=mexico[i];
  925.         }
  926. return 0;
  927. }
  928.  
  929.  
  930. char *titletext[7]={"This Program Is Distributed As Shareware",
  931.                     "TEACHER'S CHOICE tm Productions Presents",
  932.                     "An Alphabetical Drawing Game",
  933.                     "(C)Copyright by Bill Buckels 1990",
  934.                     "982 Hector Ave., Wpg.,Mb., Canada R3M 2G6",
  935.                     "Press F1 for Help",
  936.                     "DUDEL"};
  937.  
  938. int titlecords[6][2]={1,39,3,39,20,39,21,39,22,39,23,39};
  939.  
  940.  
  941. void titleblock(void)
  942. {
  943.     int i;
  944.     int cor[4];
  945.     int background = BLACK, foreground = WHITE;
  946.     int bordercolor = BLUE;
  947.  
  948.     if(ADAPTER!=HERCULES){
  949.         background =RED ;foreground =YELLOW;
  950.         background2=BLUE;foreground2=LCYAN;
  951.         }
  952.     cor[0]=0;
  953.     cor[1]=0;
  954.     cor[2]=24;
  955.     cor[3]=79;
  956.  
  957.     colorset(bordercolor,0);
  958.     cls(background,foreground);
  959.     BORDERBOX(cor,foreground2,background2,3);
  960.  
  961.     for(i=0;i!=6;i++)DMM(titletext[i],titlecords[i][0],
  962.                          titlecords[i][1],background,foreground);
  963.     ratherlargefont(titletext[6]);
  964.     playmexico();
  965. }
  966.  
  967.  
  968.  
  969.  
  970.  
  971.  
  972. void doodle()
  973. {
  974.     char c,d=1;
  975.     int DONE=0;
  976.     int OLD_SND;
  977.  
  978.     int row=0,col=0;
  979.     int front = YELLOW;
  980.     int back  = BLUE  ;
  981.     int cords[4];
  982.  
  983.     cords[0]=0;
  984.     cords[1]=0;
  985.     cords[2]=24;
  986.     cords[3]=79;
  987.  
  988.     cursoroff();
  989.  
  990.     titleblock();
  991.     cls(BLUE,YELLOW);
  992.  
  993.     DMC(row,col,d,back,front,1);
  994.  
  995.  
  996.     while(!(DONE))
  997.     {
  998.       DMC(row,col,d,back,back,1);
  999.       playmusic();
  1000.       DMC(row,col,d,back,front,1);
  1001.       playmusic();
  1002.  
  1003.     if(kbhit())
  1004.       {
  1005.       c=getch();
  1006.  
  1007.       if(c==ESCKEY)DONE++;
  1008.       else
  1009.         {
  1010.         if(c!=FUNCKEY)d=c;
  1011.  
  1012.         /*=================== inner loop ==================*/
  1013.  
  1014.         if(c==FUNCKEY)
  1015.         {
  1016.             c=getch();
  1017.             switch(c)
  1018.             {
  1019.                 /* the cursor pad controls the cursor position */
  1020.  
  1021.                 case UPARROW   :row--;break;
  1022.                 case DOWNARROW :row++;break;
  1023.                 case LEFTARROW :col--;break;
  1024.                 case RIGHTARROW:col++;break;
  1025.                 case ENDKEY    :col=79;
  1026.                 case PGDOWN    :row=24;break;
  1027.                 case HOMEKEY   :col=0;
  1028.                 case PGUP      :row=0;break;
  1029.  
  1030.                 /* F1 displays the help screen */
  1031.                 case F1:makehelp();break;
  1032.  
  1033.                 /* F2 toggles the sound switch */
  1034.  
  1035.                 case F2: mus_ctr=0;
  1036.                          if(SND==0)SND=OLD_SND+1;
  1037.                          else{
  1038.                                OLD_SND=SND;
  1039.                                SND=0;
  1040.                                }
  1041.                         break;
  1042.  
  1043.                 /* F3 and F4 select Background Colors */
  1044.                 case F3: back++ ;if(back>15)back=0;break; /* color select */
  1045.                 case F4: back-- ;if(back<0)back=15;break;
  1046.  
  1047.                 /* F5 and F6 select Foreground Colors */
  1048.                 case F5: front++;if(front>15)front=0;break;
  1049.                 case F6: front--;if(front<0)front=15;break;
  1050.  
  1051.                 /* F7 allows  entry of extended character set     */
  1052.                 case F7        :d++;  break; /* character select  */
  1053.  
  1054.                 /* F8 clears the screen to the current attributes */
  1055.                 case F8        :PAINT(cords,front,back,d);break;
  1056.  
  1057.                 /* F9 and F10 allow saving and restoring of screens */
  1058.  
  1059.                 case F9        : dudesave();break;
  1060.                 case F10       : displayfiles("BSV");
  1061.  
  1062.                 }
  1063.  
  1064.                 if(row>24)row=0;
  1065.                 if(row<0)row=24;
  1066.                 if(col<0)col=79;
  1067.                 if(col>79)col=0;
  1068.                 DMC(row,col,d,back,front,1);
  1069.                 }
  1070.                 /*============ inner loop ============*/
  1071.  
  1072.                 }
  1073.                 }
  1074.                 }
  1075.  
  1076.  
  1077. colorset(BLACK,0);
  1078. cls(BLACK,WHITE) ;
  1079. cursoron();
  1080. }
  1081.  
  1082.  
  1083.  
  1084.  
  1085.  
  1086. main()
  1087. {
  1088.     getadaptertype();
  1089.     initialization();
  1090.     doodle();
  1091.     deinitialize();
  1092.     exit(0);
  1093.  
  1094. }
  1095.  
  1096.  
  1097.